package com.snda.storage.service.multi.event;

import com.snda.storage.service.multi.ThreadWatcher;

public abstract class ServiceEvent {

	public static final int EVENT_ERROR = 0;
	public static final int EVENT_STARTED = 1;
	public static final int EVENT_COMPLETED = 2;
	public static final int EVENT_IN_PROGRESS = 3;
	public static final int EVENT_CANCELLED = 4;
	public static final int EVENT_IGNORED_ERRORS = 5;

	private int eventCode = 0;
	private Object uniqueOperationId = null;
	private Throwable t = null;
	private ThreadWatcher threadWatcher = null;
	private Throwable[] ignoredErrors = null;

	protected ServiceEvent(int eventCode, Object uniqueOperationId) {
		this.eventCode = eventCode;
		this.uniqueOperationId = uniqueOperationId;
	}

	protected void setThreadWatcher(ThreadWatcher threadWatcher) {
		this.threadWatcher = threadWatcher;
	}

	protected void setErrorCause(Throwable t) {
		this.t = t;
	}

	protected void setIgnoredErrors(Throwable[] ignoredErrors) {
		this.ignoredErrors = ignoredErrors;
	}

	public Object getUniqueOperationId() {
		return uniqueOperationId;
	}

	public int getEventCode() {
		return eventCode;
	}

	public Throwable getErrorCause() throws IllegalStateException {
		if (eventCode != EVENT_ERROR) {
			throw new IllegalStateException(
					"Error Cause is only available from EVENT_ERROR events");
		}
		return t;
	}

	public Throwable[] getIgnoredErrors() throws IllegalStateException {
		if (eventCode != EVENT_IGNORED_ERRORS) {
			throw new IllegalStateException(
					"Ignored errors are only available from EVENT_IGNORED_ERRORS events");
		}
		return ignoredErrors;
	}

	public ThreadWatcher getThreadWatcher() throws IllegalStateException {
		if (eventCode != EVENT_STARTED && eventCode != EVENT_IN_PROGRESS) {
			throw new IllegalStateException(
					"Thread Watcher is only available from EVENT_STARTED "
							+ "or EVENT_IN_PROGRESS events");
		}
		return threadWatcher;
	}

	@Override
	public String toString() {
		String eventText = eventCode == EVENT_ERROR ? "EVENT_ERROR"
	            : eventCode == EVENT_STARTED ? "EVENT_STARTED"
	                : eventCode == EVENT_COMPLETED ? "EVENT_COMPLETED"
	                    : eventCode == EVENT_IN_PROGRESS ? "EVENT_IN_PROGRESS"
	                        : eventCode == EVENT_CANCELLED ? "EVENT_CANCELLED"
	                            : eventCode == EVENT_IGNORED_ERRORS ? "EVENT_IGNORED_ERRORS"
	                                : "Unrecognised event status code: " + eventCode;

        if (eventCode == EVENT_ERROR && getErrorCause() != null) {
            return eventText + " " + getErrorCause();
        } else {
            return eventText;
        }
	}

}
